﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PardesiServices.WinControls;
using System.IO;
using System.Collections;
using System.Security.Cryptography;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Media;





namespace HashingDirectory
{
    public partial class Hashing : Form
    {
        public static bool recurseCheckbox ;
        static ArrayList filesToAdd = new ArrayList();
        private int no_of_files = 0;
        private int finished_files = 0;
        public string textToWrite = "";
        private double progress = 0;
        public string whereToSaveCSV = "";

       

        public Hashing()
        {
            InitializeComponent();
            checkRecurse.Checked = true;
            recurseCheckbox = checkRecurse.Checked;

            //clearing counters
            no_of_files = 0;
            finished_files = 0;

        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {

        }

        protected byte[] GetMD5HashFromFile(string fileName)
        {
            FileStream file = new FileStream(fileName, FileMode.Open);
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] retVal = md5.ComputeHash(file);
            file.Close();
            return retVal;
        }

        protected byte[] GetSHA1HashFromFile(string fileName)
        {
            FileStream file = new FileStream(fileName, FileMode.Open);
            HMACSHA1 sha1 = new HMACSHA1();
            byte[] retVal = sha1.ComputeHash(file);
            file.Close();
            return retVal;
        }

        protected byte[] GetSHA256HashFromFile(string fileName)
        {
            FileStream file = new FileStream(fileName, FileMode.Open);
            HMACSHA256 sha256 = new HMACSHA256();
            byte[] retVal = sha256.ComputeHash(file);
            file.Close();
            return retVal;
        }

        protected byte[] GetSHA512HashFromFile(string fileName)
        {
            FileStream file = new FileStream(fileName, FileMode.Open);
            HMACSHA512 sha512 = new HMACSHA512();
            byte[] retVal = sha512.ComputeHash(file);
            file.Close();
            return retVal;
        }



        private void GenerateHashes(string fpath)
        {
            try
            {
                textToWrite = textToWrite +

                            GetFileName(fpath) + "," +
                            GetFolderDirectory(fpath) + @"\" + GetFileName(fpath) + "," +
                            ToHash(GetMD5HashFromFile(fpath)) + "," +
                            ToHash(GetSHA1HashFromFile(fpath)) + "," +
                            ToHash(GetSHA256HashFromFile(fpath)) + "," +
                            ToHash(GetSHA512HashFromFile(fpath)) +
                            InsertLine();
            }
            catch (IOException ie)
            {
                if (ie is FileLoadException) 
                {
                    MessageBox.Show(GetFileName(fpath) + " could not be loaded");
                    System.Diagnostics.Debug.WriteLine(ie.Message);
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
            }

        }


        public string GetFolderDirectory(string fpath)
        {
            string fD = Path.GetDirectoryName(fpath);
            return fD;
        }

        public string GetFileName(string fpath)
        {
            string fN = Path.GetFileName(fpath);
            return fN;
        }

        public string InsertLine()
        {
            string NewLine = "\r\n";
            return NewLine;
        }

        public void StartFile(string fpath)
        {
            string fD = GetFolderDirectory(fpath);
            string fileName = @fD + @"\GeneratedHashes.csv";
            TextWriter ts = new StreamWriter(fileName,false);

            string TextWrite = "FileName,FilePath,MD5,SHA1,SHA256,SHA512" + InsertLine();

            ts.WriteLine(TextWrite);
            ts.Close();
        }


        public void EditFile (string fpath)
        {
            string fD = GetFolderDirectory(fpath);
            string fileName = @fD + @"\GeneratedHashes.csv";
            TextWriter ts = new StreamWriter(fileName,true);

            ts.WriteLine(textToWrite);
            ts.Close();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Process Button

            no_of_files = checkedListBox1.Items.Count;

            //fill up the arraylist

            for (int a = 0; a < checkedListBox1.Items.Count; a++)
            {
                filesToAdd.Add(checkedListBox1.Items[a].ToString());
            }



            //Creating the file
            StartFile(whereToSaveCSV);


            //Inserting Hashes

            foreach (string fpath in filesToAdd)
            {
                
               
                GenerateHashes(fpath);
                finished_files++;
                label_processedfiles.Text = finished_files.ToString();
                progress = ((double)finished_files / (double)no_of_files ) * 100D;
                try
                {
                    toolStripProgressBar1.Value = Convert.ToInt32(progress);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }

            }

            //Saving the File
            EditFile(whereToSaveCSV);


            //starting the wav vile

            Assembly asm = Assembly.GetExecutingAssembly();
            Stream sm = asm.GetManifestResourceStream("HashingDirectory.finish.wav");
            SoundPlayer sPlayer = new SoundPlayer(sm);
            sPlayer.Play();



            label4.Text = "Files Processed";

  

            MessageBox.Show("A Total of " + finished_files + " files were processed successfully", "Finished", MessageBoxButtons.OK, MessageBoxIcon.Information);



            //Removing the buttons
            
            exit_button.TabIndex = 0;

            btnOpenCSV.Visible = true;
            btnOpenFolder.Visible = true;
            processButton.Enabled = false;




        }




        public static string ByteToStr(byte [] b)
        {
            ASCIIEncoding enc = new ASCIIEncoding();
            string str = enc.GetString(b);
            return str;
        }

        public static string ToHash(byte[] b)
        {
            StringBuilder hash = new StringBuilder();
            foreach (byte hashByte in b)
            {
                hash.Append(((int)hashByte).ToString("X"));
            }
            return hash.ToString();
        }

        public void ProcessDirectory(string targetDirectory)
        {
            // Process the list of files found in the directory.
            string[] fileEntries = Directory.GetFiles(targetDirectory);
            foreach (string fileName in fileEntries)
                ProcessFile(fileName);


            if (recurseCheckbox == true)
            {

                // Recurse into subdirectories of this directory.
                string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
                foreach (string subdirectory in subdirectoryEntries)
                    ProcessDirectory(subdirectory);
            }
        }

        // Insert logic for processing found files here.
        public  void ProcessFile(string path)
        {
             //filesToAdd.Add (path);
             checkedListBox1.Items.Add(path, true);
             //no_of_files++;
        }


        private void button2_Click(object sender, EventArgs e)
        {
            //Browse Button

            FolderBrowser myBrowser = new FolderBrowser();
            myBrowser.Title = "Choose Directory to Hash";
            myBrowser.Flags = BrowseFlags.BIF_NEWDIALOGSTYLE |
                              BrowseFlags.BIF_STATUSTEXT |
                              BrowseFlags.BIF_EDITBOX; ;
            DialogResult res = myBrowser.ShowDialog();
            if (res == DialogResult.OK)
            {
                string myPath = myBrowser.DirectoryPath;
                textBox1.Text = myPath;
                ProcessDirectory(myPath);
                checkedListBox1.CheckOnClick = true;
                lbl_totalfiles.Text = no_of_files.ToString();              

            }

            //setting the folder where to save the csv
            whereToSaveCSV = myBrowser.DirectoryPath + @"\GeneratedHashes.csv";

            txt_SaveCSVPath.Text = whereToSaveCSV;


            //enablign process button
            processButton.Enabled = true;

        }

        private void checkRecurse_CheckedChanged(object sender, EventArgs e)
        {
            recurseCheckbox = checkRecurse.Checked;
        }

     
        private void button2_Click_1(object sender, EventArgs e)
        {
            //Clear the multiline box
            textBox1.Text = "";
            filesToAdd.Clear();
            checkedListBox1.Items.Clear();
            //clearing counters
            no_of_files = 0;
            finished_files = 0;
            processButton.Enabled = false;
            btnOpenCSV.Visible = false;
            btnOpenFolder.Visible = false;
            lbl_totalfiles.Text = no_of_files.ToString();
            label_processedfiles.Text = finished_files.ToString();
            whereToSaveCSV = "";
            toolStripProgressBar1.Value = 0;

        }

        private void button3_Click(object sender, EventArgs e)
        {
            //Exit the Form
            this.Close();
        }


        
        private void checkedListBox1_ItemCheck_1(object sender, ItemCheckEventArgs e)
        {
            CheckState c = e.CurrentValue;

            switch (c)
            {
                case CheckState.Checked:
                        MessageBox.Show("The Selected File will NOT be Processed");
                        e.NewValue = CheckState.Unchecked;
                        no_of_files--;
                        lbl_totalfiles.Text = no_of_files.ToString();
                        break; ;
                case CheckState.Indeterminate:
                        MessageBox.Show("The Selected File will BE Processed");
                        e.NewValue = CheckState.Checked;
                        no_of_files++;
                        lbl_totalfiles.Text = no_of_files.ToString();
                        break;
                case CheckState.Unchecked:
                        //MessageBox.Show("The Selected File will BE Processed"); 
                        e.NewValue = CheckState.Checked;
                        no_of_files++;
                        lbl_totalfiles.Text = no_of_files.ToString();
                        break;
            }
            

        }

        private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            string p = GetFolderDirectory(whereToSaveCSV) + @"\GeneratedHashes.csv";
            System.Diagnostics.Process.Start(p);
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            AboutBox1 AboutMe = new AboutBox1();
            AboutMe.Show();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start(GetFolderDirectory(whereToSaveCSV));
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            //file open

            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "Hash Files";
            ofd.AddExtension = true;
            ofd.CheckFileExists = true;
            ofd.CheckPathExists = true;
            ofd.Multiselect = true;


            ofd.ShowDialog();

            foreach (string fajl in ofd.FileNames)
            {
                string thisFpath = fajl;
                textBox1.Text = GetFolderDirectory(thisFpath);
                no_of_files++;
                //enablign process button
                processButton.Enabled = true;
                ProcessFile(thisFpath);

            }

            lbl_totalfiles.Text = no_of_files.ToString();

            //setting the folder where to save the csv
            whereToSaveCSV = textBox1.Text + @"\GeneratedHashes.csv";

            txt_SaveCSVPath.Text = whereToSaveCSV;
        }

        private void textBox1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void textBox1_DragDrop(object sender, DragEventArgs e)
        {
            string[] FileList = (string[])e.Data.GetData(DataFormats.FileDrop, false);

            foreach (string File in FileList)
            {
                textBox1.Text = GetFolderDirectory(File);
                ProcessFile(File);
                no_of_files++;
            }

            
            lbl_totalfiles.Text = no_of_files.ToString();
            //enablign process button
            processButton.Enabled = true;
            //ProcessFile(s);
        }

        private void button3_Click_2(object sender, EventArgs e)
        {
            FolderBrowser sBrowser = new FolderBrowser();
            sBrowser.Title = "Choose Where to Save The CSV";
            sBrowser.Flags = BrowseFlags.BIF_NEWDIALOGSTYLE |
                              BrowseFlags.BIF_STATUSTEXT |
                              BrowseFlags.BIF_EDITBOX; ;

            DialogResult res = sBrowser.ShowDialog();
            if (res == DialogResult.OK)
            {
                whereToSaveCSV = sBrowser.DirectoryPath + @"\GeneratedHashes.csv";

                txt_SaveCSVPath.Text = whereToSaveCSV;

            }
        }
        

    }
}
